package com.jijia.webbase.config.security;

import com.jijia.webbase.filter.JwtAuthenticationFilter;
import com.jijia.webbase.filter.UserNameAndPassWordFilter;
import com.jijia.webbase.interception.ValidationInterception;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

// config/SecurityConfig.java
// 6. Spring Security配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;


    @Autowired
    private UserNameAndPassWordFilter userNameAndPassWordFilter;

    //     配置密码编码器
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 配置认证管理器
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("https://web.stiker.top");  // 允许的前端地址
        configuration.addAllowedMethod("GET");
        configuration.addAllowedMethod("POST");
        configuration.addAllowedHeader("*");  // 允许所有请求头
        configuration.setAllowCredentials(true);  // 允许携带凭证（例如 Cookies）

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);  // 对所有路径进行配置
        return source;
    }

    @Override
    protected void configure(HttpSecurity http) {
        try {
            http.csrf().disable()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                    .authorizeRequests()
                    .antMatchers("/**").permitAll()  //放过所有请求 全部自定义控制
                    .anyRequest().authenticated()
                    .and()
                    .addFilterBefore(jwtAuthenticationFilter, FilterSecurityInterceptor.class)
                    //FilterSecurityInterceptor 是所有过滤器后的第一道拦截器 默认就有这一个拦截器 其他拦截器自定义设置 如果没有允许放行 它会验证是否认证通过 没有的话会直接拦截 所以我们需要 设置放行所有 接口
                    .addFilterBefore(userNameAndPassWordFilter, JwtAuthenticationFilter.class)
                    .formLogin().disable().cors().and().logout().disable()
            ;
            //以上说明 antMatchers("/**") 放行所有端口（会使用FilterSecurityInterceptor拦截的）（代表哪些请求路径需要authorizeRequests验证） 全部自定义控制放行 增加自定义过滤器 将FilterSecurityInterceptor放到最后
            //FilterSecurityInterceptor通过判断是否设置了 SecurityContextHolder 认证内容来判断是否放行 如下
//            List<GrantedAuthority> collect = Arrays.stream(loginUser.getUser().getRoles().split(","))
//                    .map(role -> new SimpleGrantedAuthority("ROLE_" + role))
//                    .collect(Collectors.toList());
//            UsernamePasswordAuthenticationToken authentication =
//                    new UsernamePasswordAuthenticationToken(loginUser, null, collect);
//            SecurityContextHolder.getContext().setAuthentication(authentication);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


}